package
{
	import KK.Data.ToolData;
	import KK.Input.Keyboard.ToolShortcutKey;
	import KK.System.IO.File;
	import KK.Time.FrameWheel;
	import KK.Time.IWheel;
	import KK.Grid.GridCalculate;
	
	import Protocol.Apple;
	import Protocol.CTest;
	
	import flash.display.Shape;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.KeyboardEvent;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.ui.Keyboard;
	import flash.utils.ByteArray;
	import flash.utils.Dictionary;
	[SWF(backgroundColor="0xFFFFFF")]
	public class Imprinter extends Sprite implements IWheel
	{
		static private const VESION:int=0xFFEEAAAA;
		
		static private var AUTO_INCREMENT:int=0;
		static private function get AI():int{
			return AUTO_INCREMENT++;
		}
		static private const NORMAL:int=AI;
		static private const DRAW:uint=AI;
		
		private static const DRAG_SPACE:uint=0x10000000;
		private static const DRAG_MOUSE:uint=0x20000000;
		//////////////////////////////////////////////////////
		
		
		///////////////////////////////////////////////////////////////////////
		
		
		private var _frameRate:uint=24;//帧频 
		private var _frameState:uint;//状态 
		
		private var _wheelArea:Vector.<int>;//定时轮区域
		
		private var rect:Rectangle;
		private var grid:GridCalculate;
		private var shape:Shape;
		
		private var block:Shape;
		
		private var state:int;
		private var exRect:Rectangle=new Rectangle;//前一次的坐标 
		private var exFlag:Point;
		
		public function Imprinter()
		{
			exFlag=new Point(-1,-1);
			shape=new Shape();
			block=new Shape();
			
			rect=new Rectangle();
			grid=new GridCalculate();
			FrameWheel.AddWheel(this);
			init();

		}
		
		 /**
		  * 初始化  
		  * 
		  */
		 private function init():void{ 
			 ToolData.resetMap();
			 addChild(shape);
			 addChild(block);
			 block.graphics.beginFill(0xCCFF,0.3);
			 grid.drawDiamond(graphics,ToolData.GRID_WIDTH,ToolData.GRID_HEIGHT,ToolData.GRID_WIDTH_PIXEL,ToolData.GRID_HEIGHT_PIXEL);
			 
			 stage?initListenerEvent():addEventListener(Event.ADDED_TO_STAGE,initListenerEvent);
//			 drawBlock();
			 blockGrid(new Rectangle(0,0,ToolData.GRID_WIDTH,ToolData.GRID_HEIGHT));
			 ToolData.MapData[ToolData.GRID_HEIGHT*ToolData.GRID_WIDTH];
		 }
		/**
		 * 初始化监听事件 
		 * 
		 */
		private function initListenerEvent(event:Event=null):void{
			stage.addEventListener(MouseEvent.MOUSE_DOWN,MouseDown);
			stage.addEventListener(MouseEvent.MOUSE_UP,MouseUp); 
			stage.addEventListener(MouseEvent.MOUSE_MOVE,MouseMove);
			addEventListener(Event.MOUSE_LEAVE,MouseLeave);
		}
		
		
		
		/**
		 * 鼠标移动  
		 * @param event
		 * 
		 */
		private function MouseMove(event:Event):void{
			!isDrag()&&isDraw()&&startDrawArea(mouseX,mouseY);
		}
		 
		 
		/**
		 * 鼠标点击事件  
		 * @param event
		 * 
		 */
		private function MouseDown(event:MouseEvent):void{
			exRect.x=x;
			exRect.y=y;
			exRect.width=parent.mouseX;
			exRect.height=parent.mouseY;
			MouseOpen=true;
			openDraw=true;
			!isDrag()&&initDrawArea(mouseX,mouseY);
		} 
		
		/**
		 * 鼠标弹起 
		 * @param event
		 * 
		 */
		private function MouseUp(event:MouseEvent):void{
			!isDrag()&&startDrawArea(mouseX,mouseY);
			MouseOpen=false;
			openDraw=false;
			exFlag.y=exFlag.x=-1;
		}
		
		private function MouseLeave(event:Event):void{
			MouseOpen=false;
		}
		
		/**
		 * 初始化绘制区域 
		 * @param x
		 * @param y
		 * 
		 */
		private function initDrawArea(x:Number,y:Number):void{
			rect.x=x;
			rect.y=y;
			openDraw=true
		}
		/**
		 * 标记区域 
		 * 
		 */
		private function startDrawArea(x:Number,y:Number):void{
//			flagDrawRect(x,y);
			flagDrawPoint(x,y);
		}
		
		/**
		 * 标记并绘制位置 
		 * @param x
		 * @param y
		 * 
		 */
		private function flagDrawPoint(x:Number,y:Number):void{
			var rect:Rectangle=new Rectangle();
			var point:Point=grid.TouchGrid(x,y); 
			if(point.x>=0&&point.y>=0&&point.x<ToolData.GRID_WIDTH&&ToolData.GRID_HEIGHT>point.y&&(point.x!=exFlag.x||point.y!=exFlag.y)){
				exFlag.copyFrom(point);
				rect.x=point.x;
				rect.y=point.y;
				rect.width=1;
				rect.height=1;
//				openDraw=true; 
				blockGrid(rect); 
			}
		}
		
		/**
		 * 标记绘制区域  
		 * @param x
		 * @param y
		 * 
		 */
		private function flagDrawRect(x:Number,y:Number):void{
			resetRect(x,y);
			var list:Vector.<Point>=grid.countSite(rect);
			
			openDraw=false;
			shape.graphics.clear(); 
			
			var i:int=0;
			var len:int=list.length;
			while(i<len){
				
				blockGrid(new Rectangle(list[i].x,list[i].y,1,1));
				i++;
			}
		}
		
		/**
		 * 重新计算矩形 
		 * @param x
		 * @param y
		 * @return 
		 * 
		 */
		private function resetRect(x:Number,y:Number):Rectangle{
			rect.width=(x-rect.x);
			rect.height=(y-rect.y);
			if(rect.x>x){
				rect.width=(rect.x-x);
				rect.x=x;
			}else{
				rect.width=x-rect.x;
			}
			
			if(rect.y>y){
				rect.height=(rect.y-y);
				rect.y=y;
			}else{
				rect.height=y-rect.y;
			}
			
			var reverse:Boolean=x-rect.x<0;
			if(reverse){
				rect.x=x;
				rect.y=y;
			}
			
			
			if(rect.height==0){
				rect.height=1;
			}
			if(rect.height==0){
				rect.height=1;
			}
			
			return rect;
		}
		
		/**
		 * 绘制矩形 
		 * @param rect
		 * 
		 */
		private function drawRect(rect:Rectangle):void{
			shape.graphics.clear();
			shape.graphics.beginFill(0,0.3); 
			
			shape.graphics.drawRect(rect.x,rect.y,rect.width,rect.height);
			shape.graphics.endFill();
			addChild(shape);
		}
		
		/**
		 * 绘制阻挡  
		 * 
		 */
		private function drawBlock():void{
			var point:Point=grid.getPixelPoint(0,0);
			
			
			block.graphics.moveTo(point.x,point.y);
			
			point=grid.getPixelPoint(0,ToolData.GRID_HEIGHT);
			block.graphics.lineTo(point.x,point.y);
			
			
			point=grid.getPixelPoint(ToolData.GRID_WIDTH,ToolData.GRID_HEIGHT);
			block.graphics.lineTo(point.x,point.y);
			
			point=grid.getPixelPoint(ToolData.GRID_WIDTH,0);
			block.graphics.lineTo(point.x,point.y); 
			
			
			point=grid.getPixelPoint(0,0);
			block.graphics.lineTo(point.x,point.y); 
		}
		
		/**
		 * 标记相反值 
		 * @param point
		 * 
		 */
		private function blockGrid(rect:Rectangle):void{
			


			var point:Point=grid.getPixelPoint(rect.x,rect.y);
			 
			block.graphics.moveTo(point.x,point.y);
			 
			
			point=grid.getPixelPoint(rect.x,rect.y+rect.height);
			block.graphics.lineTo(point.x,point.y);
			 
			
			point=grid.getPixelPoint(rect.x+rect.width,rect.y+rect.height);
			block.graphics.lineTo(point.x,point.y); 
			
			point=grid.getPixelPoint(rect.x+rect.width,rect.y);
			block.graphics.lineTo(point.x,point.y); 
			
			
			point=grid.getPixelPoint(rect.x,rect.y);
			block.graphics.lineTo(point.x,point.y); 
			//修改标记  
			ToolData.MapData[rect.x+ToolData.GRID_WIDTH*rect.y]^=1;
			LogInfo(rect.x+ToolData.GRID_WIDTH*rect.y,ToolData.MapData[rect.x+ToolData.GRID_WIDTH*rect.y]);
			
		}
		
		
		/**
		 * 按下space 
		 * 
		 */
		private function KeyDownSpace():void{
			SpaceOpen=true;
		}   
		
		private function KeyUpSpace():void{
			SpaceOpen=false;
		}
		
		
		/**
		 * 设置space是否开启 
		 * @param value
		 * 
		 */
		private function set SpaceOpen(value:Boolean):void{
			if(value){
				state|=DRAG_SPACE; 
			}else{
				state&=0xFFFFFFFF^DRAG_SPACE;
			} 
		}
		
		
		
		/**
		 * 开启绘制  
		 * @param value
		 * 
		 */
		private function set openDraw(value:Boolean):void{
			if(value){
				state=state&0xFFFFFFF0|DRAW;
			}else{
				state&=(0xFFFFFFFF^DRAW);
			}
		}
		/**
		 * 鼠标是否开启  
		 * @param value
		 * 
		 */
		private function set MouseOpen(value:Boolean):void{
			if(value){
				state|=DRAG_MOUSE;
				
			}else{
				state&=0xFFFFFFFF^DRAG_MOUSE;
			} 
		}
		
		/**
		 * 检查是否拖动  
		 * 
		 */
		private function isDrag():Boolean{
			var result:Boolean;
			if((state&DRAG_SPACE)==DRAG_SPACE&&(state&DRAG_MOUSE)==DRAG_MOUSE)
			{
				result=true;
			}else{
				result=false; 
			}
			
			return result;
		}
		
		/**
		 * 是否绘制
		 * @return 
		 * 
		 */
		private function isDraw():Boolean{
			return (state&DRAW)==DRAW;
		}
		 
		/**
		 * 拖动场景  
		 * 
		 */
		private function dragWord():void{ 
 			x=parent.mouseX-exRect.width+exRect.x;
			y=parent.mouseY-exRect.height+exRect.y; 
			
		}
		
		
		/**
		 * 保存数据  
		 * 
		 */
		private function Save():void{
			File.Save(ToolData.MapData);
		}
		
		/**
		 * 获取帧频  
		 * @return 
		 * 
		 */
		public function get frameRate():uint{
			return _frameRate;
		}
		
		/**
		 * 强制更新  
		 * 
		 */
		public function UpdateFrame():void{
			ToolData.keyboard.justKeyPressed("SPACE")&&KeyDownSpace();
			ToolData.keyboard.justKeyRelease("SPACE")&&KeyUpSpace();
			
			isDrag()&&dragWord();
			//isDraw()&&startDrawArea(mouseX,mouseY);  
			ToolData.keyboard.keepKeyPressed("CONTROL")&&ToolData.keyboard.keepKeyPressed("A")&&Save();
		}
		
		/**
		 * 返回定时器区域 
		 * @return 
		 * 
		 */
		public function getWheelArea():Vector.<int>{
			return _wheelArea;
		}
		
		/**
		 * 设定定时器区域  
		 * @param value
		 * 
		 */
		public function setWheelArea(value:Vector.<int>):void{
			_wheelArea=value;
		}

		/**
		 * 设置bytes 
		 * @param bytes
		 * 
		 */
		public function setBytes(bytes:ByteArray):void{
			var vesion:int=bytes.readInt();
			if(vesion!=VESION){
				LogInfo("文件格式不正确 .");
			}
			ToolData.MapData[0]=1;
			block.graphics.clear();
			block.graphics.beginFill(0xCCFF,0.3);
			
			blockGrid(new Rectangle(0,0,ToolData.GRID_WIDTH,ToolData.GRID_HEIGHT));
			
			restore(bytes);
		}
		
		/**
		 * 恢复 
		 * 
		 */
		private function restore(bytes:ByteArray):void{
			var begin:int=bytes.position;
			var row:int=0;
			var col:int=0;
			ToolData.resetMap();
			var rect:Rectangle=new Rectangle();
			
			rect.width=rect.height=1;
			
			for(col=0;col<ToolData.GRID_WIDTH;col++){
				rect.y=col;
				for(row=0;row<ToolData.GRID_HEIGHT;row++){
					rect.x=row;
					if(bytes[col*ToolData.GRID_WIDTH+row+begin]==1){
						blockGrid(rect);
					}
				}
				
			}
			
		}
		
		/**
		 * 获取数据  
		 * @param bytes
		 * 
		 */
		public function getBytes(bytes:ByteArray):void{
			
			if(bytes){
				bytes.writeInt(VESION);
				bytes.writeBytes(ToolData.MapData,0,ToolData.GRID_HEIGHT*ToolData.GRID_WIDTH);
			}else{
				LogError("bytes is null");
			}
			
		}
		
		/**
		 * 获取状态  
		 * @return 
		 * 
		 */
		public function get frameState():Boolean{
			return _frameState==FrameWheel.START;
		}
		
		/**
		 * 停止 
		 * 
		 */
		public function Stop():void{ 
			_frameState=FrameWheel.STOP;
		}
		
		/**
		 * 定时器开始  
		 * 
		 */
		public function Start():void{
			_frameState=FrameWheel.START;
		}
	}
}